home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / vindictr.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  15KB  |  581 lines

  1. /***************************************************************************
  2.  
  3.     vidhrdw/vindictr.c
  4.  
  5.     Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************
  8.  
  9.     Playfield encoding
  10.     ------------------
  11.         1 16-bit word is used
  12.  
  13.         Word 1:
  14.             Bit  15    = horizontal flip
  15.             Bits 13-15 = palette
  16.             Bits  0-12 = image index
  17.  
  18.  
  19.     Motion Object encoding
  20.     ----------------------
  21.         4 16-bit words are used
  22.  
  23.         Word 1:
  24.             Bits  0-14 = image index
  25.  
  26.         Word 2:
  27.             Bits  7-15 = X position
  28.             Bits  0-3  = palette
  29.  
  30.         Word 3:
  31.             Bits  7-14 = Y position
  32.             Bit   6    = horizontal flip
  33.             Bits  3-5  = width in tiles (ranges from 1-8)
  34.             Bits  0-2  = height in tiles (ranges from 1-8)
  35.  
  36.         Word 4:
  37.             Bits  0-9  = link to the next image to display
  38.  
  39.  
  40.     Alpha layer encoding
  41.     --------------------
  42.         1 16-bit word is used
  43.  
  44.         Word 1:
  45.             Bit  15    = transparent/opaque
  46.             Bit  10-13 = palette
  47.             Bits  0-9  = image index
  48.  
  49. ***************************************************************************/
  50.  
  51. #include "driver.h"
  52. #include "machine/atarigen.h"
  53. #include "vidhrdw/generic.h"
  54.  
  55. #define XCHARS 42
  56. #define YCHARS 30
  57.  
  58. #define XDIM (XCHARS*8)
  59. #define YDIM (YCHARS*8)
  60.  
  61.  
  62. /*************************************
  63.  *
  64.  *    Statics
  65.  *
  66.  *************************************/
  67.  
  68. struct mo_data
  69. {
  70.     struct osd_bitmap *bitmap;
  71.     UINT8 color_xor;
  72. };
  73.  
  74. static struct atarigen_pf_state pf_state;
  75.  
  76.  
  77.  
  78. /*************************************
  79.  *
  80.  *    Prototypes
  81.  *
  82.  *************************************/
  83.  
  84. static const UINT8 *update_palette(void);
  85.  
  86. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  87. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  88.  
  89. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  90. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  91.  
  92.  
  93.  
  94. /*************************************
  95.  *
  96.  *    Video system start
  97.  *
  98.  *************************************/
  99.  
  100. int vindictr_vh_start(void)
  101. {
  102.     static struct atarigen_mo_desc mo_desc =
  103.     {
  104.         1024,                /* maximum number of MO's */
  105.         8,                   /* number of bytes per MO entry */
  106.         2,                   /* number of bytes between MO words */
  107.         0,                   /* ignore an entry if this word == 0xffff */
  108.         3, 0, 0x3ff,         /* link = (data[linkword] >> linkshift) & linkmask */
  109.         0                    /* reverse order */
  110.     };
  111.  
  112.     static struct atarigen_pf_desc pf_desc =
  113.     {
  114.         8, 8,                /* width/height of each tile */
  115.         64, 64                /* number of tiles in each direction */
  116.     };
  117.  
  118.     /* reset statics */
  119.     memset(&pf_state, 0, sizeof(pf_state));
  120.  
  121.     /* initialize the playfield */
  122.     if (atarigen_pf_init(&pf_desc))
  123.         return 1;
  124.  
  125.     /* initialize the motion objects */
  126.     if (atarigen_mo_init(&mo_desc))
  127.     {
  128.         atarigen_pf_free();
  129.         return 1;
  130.     }
  131.  
  132.     return 0;
  133. }
  134.  
  135.  
  136.  
  137. /*************************************
  138.  *
  139.  *    Video system shutdown
  140.  *
  141.  *************************************/
  142.  
  143. void vindictr_vh_stop(void)
  144. {
  145.     atarigen_pf_free();
  146.     atarigen_mo_free();
  147. }
  148.  
  149.  
  150.  
  151. /*************************************
  152.  *
  153.  *    Playfield RAM write handler
  154.  *
  155.  *************************************/
  156.  
  157. WRITE_HANDLER( vindictr_playfieldram_w )
  158. {
  159.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  160.     int newword = COMBINE_WORD(oldword, data);
  161.  
  162.     if (oldword != newword)
  163.     {
  164.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  165.         atarigen_pf_dirty[offset / 2] = 0xff;
  166.     }
  167. }
  168.  
  169.  
  170.  
  171. /*************************************
  172.  *
  173.  *    Palette RAM write handler
  174.  *
  175.  *************************************/
  176.  
  177. WRITE_HANDLER( vindictr_paletteram_w )
  178. {
  179.     static const int ztable[16] =
  180.         { 0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11 };
  181.  
  182.     int oldword = READ_WORD(&paletteram[offset]);
  183.     int newword = COMBINE_WORD(oldword, data);
  184.     int i, r, g, b;
  185.  
  186.     WRITE_WORD(&paletteram[offset], newword);
  187.  
  188.     i = ztable[(newword >> 12) & 15];
  189.     r = ((newword >> 8) & 15) * i;
  190.     g = ((newword >> 4) & 15) * i;
  191.     b = ((newword >> 0) & 15) * i;
  192.  
  193.     offset /= 2;
  194.     palette_change_color(offset, r, g, b);
  195. }
  196.  
  197.  
  198.  
  199. /*************************************
  200.  *
  201.  *    Periodic scanline updater
  202.  *
  203.  *************************************/
  204.  
  205. void vindictr_scanline_update(int scanline)
  206. {
  207.     UINT16 *base = (UINT16 *)&atarigen_alpharam[((scanline / 8) * 64 + XCHARS) * 2];
  208.     int x;
  209.  
  210.     /* update the playfield with the previous parameters */
  211.     atarigen_pf_update(&pf_state, scanline);
  212.  
  213.     /* update the MOs from the SLIP table */
  214.     atarigen_mo_update_slip_512(atarigen_spriteram, pf_state.vscroll, scanline, &atarigen_alpharam[0xf80]);
  215.  
  216.     /* update the current parameters */
  217.     if ((UINT8 *)base < &atarigen_alpharam[0xf80])
  218.         for (x = XCHARS; x < 64; x++)
  219.         {
  220.             UINT16 data = *base++;
  221.             UINT16 command = data & 0x7e00;
  222.  
  223.             if (command == 0x7400)
  224.                 pf_state.param[0] = data & 7;
  225.             else if (command == 0x7600)
  226.                 pf_state.hscroll = data & 0x1ff;
  227.             else if (command == 0x7800)
  228.                 ;
  229.             else if (command == 0x7a00)
  230.                 ;
  231.             else if (command == 0x7c00)
  232.                 ;
  233.             else if (command == 0x7e00)
  234.             {
  235.                 /* a new vscroll latches the offset into a counter; we must adjust for this */
  236.                 int offset = scanline + 8;
  237.                 if (offset >= 240)
  238.                     offset -= 240;
  239.                 pf_state.vscroll = (data - offset) & 0x1ff;
  240.             }
  241.         }
  242. }
  243.  
  244.  
  245.  
  246. /*************************************
  247.  *
  248.  *    Main refresh
  249.  *
  250.  *************************************/
  251.  
  252. void vindictr_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  253. {
  254.     /* update the palette, and mark things dirty */
  255.     if (update_palette())
  256.         memset(atarigen_pf_dirty, 0xff, atarigen_playfieldram_size / 2);
  257.  
  258.     /* draw the playfield */
  259.     memset(atarigen_pf_visit, 0, 64*64);
  260.     atarigen_pf_process(pf_render_callback, bitmap, &Machine->drv->visible_area);
  261.  
  262.     /* draw the motion objects */
  263.     atarigen_mo_process(mo_render_callback, bitmap);
  264.  
  265.     /* draw the alphanumerics */
  266.     {
  267.         const struct GfxElement *gfx = Machine->gfx[1];
  268.         int x, y, offs;
  269.  
  270.         for (y = 0; y < YCHARS; y++)
  271.             for (x = 0, offs = y * 64; x < XCHARS; x++, offs++)
  272.             {
  273.                 int data = READ_WORD(&atarigen_alpharam[offs * 2]);
  274.                 int code = data & 0x3ff;
  275.                 int opaque = data & 0x8000;
  276.  
  277.                 if (code || opaque)
  278.                 {
  279.                     int color = ((data >> 10) & 0xf) | ((data >> 9) & 0x20);
  280.                     drawgfx(bitmap, gfx, code, color, 0, 0, 8 * x, 8 * y, 0, opaque ? TRANSPARENCY_NONE : TRANSPARENCY_PEN, 0);
  281.                 }
  282.             }
  283.     }
  284.  
  285.     /* update onscreen messages */
  286.     atarigen_update_messages();
  287. }
  288.  
  289.  
  290.  
  291. /*************************************
  292.  *
  293.  *    Palette management
  294.  *
  295.  *************************************/
  296.  
  297. static const UINT8 *update_palette(void)
  298. {
  299.     UINT16 pf_map[16], al_map[64], mo_map[16];
  300.     int i, j;
  301.  
  302.     /* reset color tracking */
  303.     memset(mo_map, 0, sizeof(mo_map));
  304.     memset(pf_map, 0, sizeof(pf_map));
  305.     memset(al_map, 0, sizeof(al_map));
  306.     palette_init_used_colors();
  307.  
  308.     /* update color usage for the playfield */
  309.     atarigen_pf_process(pf_color_callback, pf_map, &Machine->drv->visible_area);
  310.  
  311.     /* update color usage for the mo's */
  312.     atarigen_mo_process(mo_color_callback, mo_map);
  313.  
  314.     /* update color usage for the alphanumerics */
  315.     {
  316.         const unsigned int *usage = Machine->gfx[1]->pen_usage;
  317.         int x, y, offs;
  318.  
  319.         for (y = 0; y < YCHARS; y++)
  320.             for (x = 0, offs = y * 64; x < XCHARS; x++, offs++)
  321.             {
  322.                 int data = READ_WORD(&atarigen_alpharam[offs * 2]);
  323.                 int code = data & 0x3ff;
  324.                 int color = ((data >> 10) & 0xf) | ((data >> 9) & 0x20);
  325.                 al_map[color] |= usage[code];
  326.             }
  327.     }
  328.  
  329.     /* rebuild the playfield palette */
  330.     for (i = 0; i < 16; i++)
  331.     {
  332.         UINT16 used = pf_map[i];
  333.         if (used)
  334.             for (j = 0; j < 16; j++)
  335.                 if (used & (1 << j))
  336.                     palette_used_colors[0x200 + i * 16 + j] = PALETTE_COLOR_USED;
  337.     }
  338.  
  339.     /* rebuild the motion object palette */
  340.     for (i = 0; i < 16; i++)
  341.     {
  342.         UINT16 used = mo_map[i];
  343.         if (used)
  344.         {
  345.             palette_used_colors[0x100 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  346.             palette_used_colors[0x100 + i * 16 + 1] = PALETTE_COLOR_TRANSPARENT;
  347.             for (j = 2; j < 16; j++)
  348.                 if (used & (1 << j))
  349.                     palette_used_colors[0x100 + i * 16 + j] = PALETTE_COLOR_USED;
  350.         }
  351.     }
  352.  
  353.     /* rebuild the alphanumerics palette */
  354.     for (i = 0; i < 64; i++)
  355.     {
  356.         UINT16 used = al_map[i];
  357.         if (used)
  358.             for (j = 0; j < 4; j++)
  359.                 if (used & (1 << j))
  360.                     palette_used_colors[0x000 + i * 4 + j] = PALETTE_COLOR_USED;
  361.     }
  362.  
  363.     /* recalc */
  364.     return palette_recalc();
  365. }
  366.  
  367.  
  368.  
  369. /*************************************
  370.  *
  371.  *    Playfield palette
  372.  *
  373.  *************************************/
  374.  
  375. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  376. {
  377.     const unsigned int *usage = &Machine->gfx[0]->pen_usage[state->param[0] * 0x1000];
  378.     UINT16 *colormap = (UINT16 *)param;
  379.     int x, y;
  380.  
  381.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  382.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  383.         {
  384.             int offs = x * 64 + y;
  385.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  386.             int code = data & 0xfff;
  387.             int color = (data >> 11) & 14;
  388.             colormap[color] |= usage[code];
  389.             colormap[color ^ 1] |= usage[code];
  390.  
  391.             /* also mark unvisited tiles dirty */
  392.             if (!atarigen_pf_visit[offs]) atarigen_pf_dirty[offs] = 0xff;
  393.         }
  394. }
  395.  
  396.  
  397.  
  398. /*************************************
  399.  *
  400.  *    Playfield rendering
  401.  *
  402.  *************************************/
  403.  
  404. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  405. {
  406.     const struct GfxElement *gfx = Machine->gfx[0];
  407.     struct osd_bitmap *bitmap = param;
  408.     int bank = state->param[0];
  409.     int x, y;
  410.  
  411.     /* first update any tiles whose color is out of date */
  412.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  413.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  414.         {
  415.             int offs = x * 64 + y;
  416.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  417.  
  418.             /* update only if dirty */
  419.             if (atarigen_pf_dirty[offs] != bank)
  420.             {
  421.                 int color = 16 + ((data >> 11) & 14);
  422.                 int code = bank * 0x1000 + (data & 0xfff);
  423.                 int hflip = data & 0x8000;
  424.  
  425.                 drawgfx(atarigen_pf_bitmap, gfx, code, color, hflip, 0, 8 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  426.                 atarigen_pf_dirty[offs] = bank;
  427.             }
  428.  
  429.             /* track the tiles we've visited */
  430.             atarigen_pf_visit[offs] = 1;
  431.         }
  432.  
  433.     /* then blast the result */
  434.     x = -state->hscroll;
  435.     y = -state->vscroll;
  436.     copyscrollbitmap(bitmap, atarigen_pf_bitmap, 1, &x, 1, &y, clip, TRANSPARENCY_NONE, 0);
  437. }
  438.  
  439.  
  440.  
  441. /*************************************
  442.  *
  443.  *    Playfield overrendering
  444.  *
  445.  *************************************/
  446.  
  447. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  448. {
  449.     const struct GfxElement *gfx = Machine->gfx[0];
  450.     const struct mo_data *modata = param;
  451.     struct osd_bitmap *bitmap = modata->bitmap;
  452.     int color_xor = modata->color_xor;
  453.     int bank = state->param[0];
  454.     int x, y;
  455.  
  456.     /* first update any tiles whose color is out of date */
  457.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  458.     {
  459.         int sy = (8 * y - state->vscroll) & 0x1ff;
  460.         if (sy >= YDIM) sy -= 0x200;
  461.  
  462.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  463.         {
  464.             int offs = x * 64 + y;
  465.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  466.             int color = 16 + ((data >> 11) & 14);
  467.             int code = bank * 0x1000 + (data & 0xfff);
  468.             int hflip = data & 0x8000;
  469.             int sx = (8 * x - state->hscroll) & 0x1ff;
  470.             if (sx >= XDIM) sx -= 0x200;
  471.  
  472.             drawgfx(bitmap, gfx, code, color ^ color_xor, hflip, 0, sx, sy, 0, TRANSPARENCY_THROUGH, palette_transparent_pen);
  473.         }
  474.     }
  475. }
  476.  
  477.  
  478.  
  479. /*************************************
  480.  *
  481.  *    Motion object palette
  482.  *
  483.  *************************************/
  484.  
  485. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  486. {
  487.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  488.     UINT16 *colormap = param;
  489.     int code = data[0] & 0x7fff;
  490.     int hsize = ((data[2] >> 3) & 7) + 1;
  491.     int vsize = (data[2] & 7) + 1;
  492.     int color = data[1] & 0x000f;
  493.     int tiles = hsize * vsize;
  494.     UINT16 temp = 0;
  495.     int i;
  496.  
  497.     for (i = 0; i < tiles; i++)
  498.         temp |= usage[code++];
  499.     colormap[color] |= temp;
  500. }
  501.  
  502.  
  503.  
  504. /*************************************
  505.  *
  506.  *    Motion object rendering
  507.  *
  508.  *************************************/
  509.  
  510. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  511. {
  512.     const struct GfxElement *gfx = Machine->gfx[0];
  513.     const unsigned int *usage = gfx->pen_usage;
  514.     struct osd_bitmap *bitmap = param;
  515.     unsigned int total_usage = 0;
  516.     struct rectangle pf_clip;
  517.     int x, y, sx, sy;
  518.  
  519.     /* extract data from the various words */
  520.     int code = data[0] & 0x7fff;
  521.     int color = data[1] & 0x000f;
  522.     int ypos = -pf_state.vscroll - (data[2] >> 7);
  523.     int hflip = data[2] & 0x0040;
  524.     int hsize = ((data[2] >> 3) & 7) + 1;
  525.     int vsize = (data[2] & 7) + 1;
  526.     int xpos = -pf_state.hscroll + (data[1] >> 7);
  527.     int xadv;
  528.  
  529.     /* adjust for height */
  530.     ypos -= vsize * 8;
  531.  
  532.     /* adjust the final coordinates */
  533.     xpos &= 0x1ff;
  534.     ypos &= 0x1ff;
  535.     if (xpos >= XDIM) xpos -= 0x200;
  536.     if (ypos >= YDIM) ypos -= 0x200;
  537.  
  538.     /* determine the bounding box */
  539.     atarigen_mo_compute_clip_8x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  540.  
  541.     /* adjust for h flip */
  542.     if (hflip)
  543.         xpos += (hsize - 1) * 8, xadv = -8;
  544.     else
  545.         xadv = 8;
  546.  
  547.     /* loop over the height */
  548.     for (y = 0, sy = ypos; y < vsize; y++, sy += 8)
  549.     {
  550.         /* clip the Y coordinate */
  551.         if (sy <= clip->min_y - 8)
  552.         {
  553.             code += hsize;
  554.             continue;
  555.         }
  556.         else if (sy > clip->max_y)
  557.             break;
  558.  
  559.         /* loop over the width */
  560.         for (x = 0, sx = xpos; x < hsize; x++, sx += xadv, code++)
  561.         {
  562.             /* clip the X coordinate */
  563.             if (sx <= -8 || sx >= XDIM)
  564.                 continue;
  565.  
  566.             /* draw the sprite */
  567.             drawgfx(bitmap, gfx, code, color, hflip, 0, sx, sy, clip, TRANSPARENCY_PEN, 0);
  568.             total_usage |= usage[code];
  569.         }
  570.     }
  571.  
  572.     /* overrender the playfield */
  573.     if (total_usage & 0x0002)
  574.     {
  575.         struct mo_data modata;
  576.         modata.bitmap = bitmap;
  577.         modata.color_xor = (color == 0) ? 0 : 1;
  578.         atarigen_pf_process(pf_overrender_callback, &modata, &pf_clip);
  579.     }
  580. }
  581.